#include "Queue.h"
Status InitQueue(Queue* Q) {
    if (Q == NULL) {
        return ERROR;
    }

    (*Q).front = (*Q).rear = (QueuePtr)malloc(sizeof(QNode));
    if (!(*Q).front) {
        exit(OVERFLOW);
    }

    (*Q).front->next = NULL;

    return OK;
}
Status DestroyQueue(Queue* Q) {
    if (Q == NULL) {
        return ERROR;
    }

    while ((*Q).front) {
        (*Q).rear = (*Q).front->next;
        free((*Q).front);
        (*Q).front = (*Q).rear;
    }

    return OK;
}
Status ClearQueue(Queue* Q) {
    if (Q == NULL) {
        return ERROR;
    }

    (*Q).rear = (*Q).front->next;

    while ((*Q).rear) {
        (*Q).front->next = (*Q).rear->next;
        free((*Q).rear);
        (*Q).rear = (*Q).front->next;
    }

    (*Q).rear = (*Q).front;

    return OK;
}
Status QueueEmpty(Queue* Q) {
    if (Q->front == Q->rear) {
        return TRUE;
    }
    else {
        return FALSE;
    }
}
int QueueLength(Queue* Q) {
    int count = 0;
    QueuePtr p = Q->front;

    while (p != Q->rear) {
        count++;
        p = p->next;
    }

    return count;
}
Status GetHead(Queue* Q, QElemType* e) {
    QueuePtr p;

    if (Q->front == NULL || Q->front == Q->rear) {
        return ERROR;
    }

    p = Q->front->next;
    *e = p->data;

    return OK;
}
Status EnQueue(Queue* Q, QElemType e) {
    QueuePtr p;

    if (Q == NULL || (*Q).front == NULL) {
        return ERROR;
    }

    p = (QueuePtr)malloc(sizeof(QNode));
    if (!p) {
        exit(OVERFLOW);
    }

    p->data = e;
    p->next = NULL;

    (*Q).rear->next = p;
    (*Q).rear = p;

    return OK;
}
Status DeQueue(Queue* Q, QElemType* e) {
    QueuePtr p;

    if (Q == NULL || (*Q).front == NULL || (*Q).front == (*Q).rear) {
        return ERROR;
    }

    p = (*Q).front->next;
    *e = p->data;

    (*Q).front->next = p->next;
    if ((*Q).rear == p) {
        (*Q).rear = (*Q).front;
    }

    free(p);

    return OK;
}
Status QueueTraverse(Queue* Q, void(Visit)(QElemType)) {
    QueuePtr p;

    if (Q->front == NULL) {
        return ERROR;
    }

    p = Q->front->next;

    while (p != NULL) {
        Visit(p->data);
        p = p->next;
    }

    printf("\n");

    return OK;
}